Adding WebSocket Support#968
Conversation
Add an optional event parameter to the onClose and onOpen callbacks Incorporates the api_key as a searchParam in the websocket URL
Lots of refactoring based on Niels' feedback, including a subscription model that can be used by consumers This will manage the websocket connection entirely
make this look more like the kotlin sdk, which uses a subscription model
…n the websocket status Pulls out the reconnect interval to a separate config
|
src/generated-client/models/outbound-web-socket-message-type.ts
Outdated
Show resolved
Hide resolved
Moving OutboundWebSocketMessageType to types folder (oopsies) Setting WebSocketService when authentication methods are called Closing the websocketservice and disposing when a logout occurs Extracting PERIODIC_LISTENER_INTERVAL to a config const Setting WebSocket URL PATH as a config const exporting types from the websocket index adding WebSocketStatus as a type adding a close function that can be called when the user logs out
added getters for fields moved websocket closure to the api instance instead of the SessionApi fix linting, fix tests
adjust constructor params in the WebSocketService Extract constants from api.ts to separate constants file
instantiate websocketservice on api construction if accessToken is provided
thornbill
left a comment
There was a problem hiding this comment.
A lot of the new files are missing the license header 🙂
|
Please update the CHANGELOG also. 🙏 |
Updated! |
Fixed 🙂 |
establish intervals for websocket start messages remove configs.ts in leiu of constants update tests accordingly
…als to be provided in the api constructor Set webSocket as a readonly, defined field Update tests to cover new functionality and refactoring Update documentation, add example code snippets
| */ | ||
| createApi(basePath: string, accessToken?: string, axiosInstance?: AxiosInstance): Api { | ||
| return new Api(basePath, this.clientInfo, this.deviceInfo, accessToken, axiosInstance); | ||
| createApi(basePath: string, accessToken?: string, axiosInstance?: AxiosInstance, webSocketSubscriptionIntervals?: WebSocketSubscriptionIntervals): Api { |
There was a problem hiding this comment.
Outside of the scope for this PR, but I think it would make sense to change this function to take a single object instead. That is easier to work with when options change in future releases.
switch to "addEventListener" instead of onevent for websockets update tests make websocketservice lazily instantiated
| this.getUri(WEBSOCKET_URL_PATH, { | ||
| [AUTHORIZATION_PARAMETER]: this.accessToken | ||
| }), |
There was a problem hiding this comment.
Doesn't really work great when there is no access token (yet)
| * | ||
| * @returns A function which can be invoked to remove the added listeners | ||
| */ | ||
| subscribe<T extends OutboundWebSocketMessageType>(messageTypes: T[], onMessage: SocketMessageHandler<T>) { |
There was a problem hiding this comment.
What happens if subscribe() is called but there is no access token set?
There was a problem hiding this comment.
My plan is that the webSocket field on the api instance will be undefined until there is an access token set, but let me know if that's undesired behavior 👍
There was a problem hiding this comment.
Feels weird, because you can also set an access token, start websockets, then unset the access token. At that point the websocket service is accessible.
Set WebSocketService to undefined if there is no accessToken present to work with The update function will optionally update the websocketservice url if the basepath or accesstoken are updated
src/websocket/types.ts
Outdated
|
|
||
| export type OutboundWebSocketMessageType = OutboundWebSocketMessage['MessageType']; | ||
|
|
||
| export class PeriodicListenerInterval { |
There was a problem hiding this comment.
This is an implementation, not a type 😉
address when the token is cleared (e.g. on a logout) Keep the websocketservice around, but prevent reconnecting move PeriodicEventListener to "models.ts" and export properly
|
@kody start-review |
Kody Review CompleteGreat news! 🎉 Keep up the excellent work! 🚀 Kody Guide: Usage and ConfigurationInteracting with Kody
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
|
The new test file |



Adds websocket support to the SDK
Facilitates the initialization and lifecycle of a WebSocket, abstracting the nuts and bolts of this connection from the consumer.
Creates a subscription model for socket events similar to the Kotlin SDK (thank you @nielsvanvelzen), and establishes a constant "SUBSCRIPTION_REGISTRY", of which
startandstopmessages can be supplied to the server (i.e., when requestingSessions)Covers #966
This pull request introduces comprehensive WebSocket support to the SDK, enabling real-time communication with Jellyfin servers.
Key changes include:
Apiclass now includes awebSocketfield, providing access to a newWebSocketServiceinstance. This service manages the WebSocket connection lifecycle.OutboundWebSocketMessageTypes (e.g.,Sessions,ActivityLogEntry,ScheduledTasksInfo) to receive real-time updates from the Jellyfin server.WebSocketServicehandles connection establishment, automatic reconnection with exponential backoff in case of disconnections, and graceful closure.Apiinstance'saccessTokenorbasePathis modified via the newApi.update()method. Clearing theaccessTokenwill disconnect the WebSocket.ForceKeepAlivemessages from the server by sendingKeepAlivemessages to maintain the connection.buildWebSocketUrlutility function is introduced to correctly convert HTTP/HTTPS URLs to their WS/WSS equivalents.